import controller from '../core/controller'
import {get,post} from '../core/route'
import {login} from '../decorater/auth'
import {db, tran, id} from '../core/db/mysql/db'
import Query from '../core/db/mysql/query'
import i18n from "../core/i18n";
import MenuValidator from '../validator/menu'
import Validator from '../core/validator'

function sort(menu) {
    let menu_count = menu.length,
        sorted = []
    for(let i = 0; i < menu_count; i++) {
        let cur = menu[i]
        if(cur.pid === 0) {
            sorted.push(cur)
        }
        cur.childs = [], cur.buttons = []
        for(let j = 0;j < menu_count; j++) {
            let child = menu[j]
            if(child.pid === cur.id) {
                if(child.type === 1) {
                    cur.childs.push(child)
                    //child.parent = cur
                }else {
                    cur.buttons.push(child)
                    //child.parent = cur
                }
            }
        }
    }
    return sorted
}
function rebuild(sorted, flag = '') {
    let ret = []
    for(let i = 0;i < sorted.length; i++) {
        sorted[i].name = (flag === ''?flag:flag + '|__' ) + sorted[i].name
        ret.push(sorted[i])
        if(sorted[i].childs.length > 0) {
            let tmp = rebuild(sorted[i].childs, flag + '&nbsp;&nbsp;&nbsp;&nbsp;')
            ret = ret.concat(tmp)
        }
    }
    return ret
}
function sort2(menu) {
    let menu_count = menu.length,
        sorted = [],ret = []
    for(let i = 0; i < menu_count; i++) {
        let cur = menu[i]
        if(cur.pid === 0) {
            sorted.push(cur)
        }
        cur.childs = []
        for(let j = 0;j < menu_count; j++) {
            let child = menu[j]
            if(child.pid === cur.id) {
                cur.childs.push(child)
            }
        }
    }
    ret = rebuild(sorted, '')
    return ret
}



@controller()
export default class menu{
    //返回权限数据
    @login
    @get('/api/menu')
    async api() {
        try{
            await db(async conn => {
                let Menu = new Query(conn, 'sys_menu'),
                    menus = await Menu.alias('m')
                        .fields('m.*')
                        .join('sys_auth_record ar','ar.menu_id = m.id','LEFT')
                        .join('sys_user_auth ua','ua.auth_id = ar.auth_id','LEFT')
                        .where('ua.user_id',this.session.userid)
                        .where('m.type','in','1,2')
                        .where('m.status',1)
                        .order('m.sort desc')
                        .select()
                this.assign('menus', sort(menus))
            })
            return this.setCode(0).setMsg(i18n.success).json()
        }catch(error) {
            console.log(error)
            return this.setCode(500).setMsg(i18n.sys_err).json()
        }
    }
    @login
    @get('/api/buttons')
    async buttons() {
        try{
            await db(async conn => {
                console.log(this.params)
                let QMenu = new Query(conn, 'sys_menu'),
                    menus = await QMenu.alias('m').fields('m.*')
                        .join('sys_menu m2','m2.id = m.pid','LEFT')
                        .join('sys_auth_record ar','ar.menu_id = m.id','LEFT')
                        .join('sys_user_auth ua','ua.auth_id = ar.auth_id','LEFT')
                        .where('ua.user_id',this.session.userid)
                        .where('m.type', 2)
                        .where('m.status',1)
                        .where('m2.rule', this.params.rule)
                        .order('m.sort desc')
                        .select()
                this.assign('buttons', menus)
            })
            return this.setCode(0).setMsg(i18n.success).json()
        }catch(error) {
            console.log(error)
            return this.setCode(500).setMsg(i18n.sys_err).json()
        }
    }


    @login
    @get('/menu')
    async list() {
        return await this.fetch('menu')
    }
    @login
    @post('/menu/add')
    async add() {
        let validator = new Validator(MenuValidator)
        let res = await validator.check(this.params)
        if(res !== true) {
            return this.setCode(1).setMsg(res).json()
        }
        return await tran(async conn => {
            let QMenu = new Query(conn, 'sys_menu'),
                QAuthRecord = new Query(conn, 'sys_auth_record')
            try{
                await QMenu.insert(this.params)
                let mid =  await id(conn)
                let RAuthRecord = []
                this.session.userid !== 1 &&  RAuthRecord.push({auth_id: this.session.userid, menu_id: mid})
                RAuthRecord.push({auth_id:1, menu_id: mid})
                await QAuthRecord.insertAll(RAuthRecord)
                return true
            }catch(err) {
                console.log(err)
                return false
            }
        })?this.setCode(0).setMsg(i18n.sys_success).json():this.setCode(1).setMsg(i18n.sys_err).json()
    }
    @login
    @post('/menu/edit')
    async edit() {
        let validator = new Validator(MenuValidator)
        let res = await validator.check(this.params)
        if(res !== true) {
            return this.setCode(1).setMsg(res).json()
        }
        return await tran(async conn => {
            let QMenu = new Query(conn, 'sys_menu')
            try{
                await QMenu.where('id', this.params.id).update(this.params)
                return true
            }catch(err) {
                console.log(err)
                return false
            }
        })?this.setCode(0).setMsg(i18n.sys_success).json():this.setCode(1).setMsg(i18n.sys_err).json()
    }
    @login
    @post('/menu/del')
    async del() {
        let id = this.params.id
        return await db(async conn => {
            let QMenu = new Query(conn, 'sys_menu')
            try{
                await QMenu.where('id', id).delete()
                return true
            }catch(err) {
                return false
            }
        })?this.setCode(0).setMsg(i18n.sys_success).json():this.setCode(1).setMsg(i18n.sys_err).json()
    }

    @login
    @get('/api/sorted')
    async sorted() {
        try{
            await db(async conn => {
                let Menu = new Query(conn, 'sys_menu'),
                  menus = await Menu.alias('m')
                    .fields('m.*')
                    .join('sys_auth_record ar', 'ar.menu_id = m.id', 'LEFT')
                    .join('sys_user_auth ua', 'ua.auth_id = ar.auth_id', 'LEFT')
                    .where('ua.user_id', this.session.userid)
                    .order('m.sort asc')
                    .select()
                let sorted = sort(menus)
                this.assign('menus', sorted)
            })
            return this.setCode(0).setMsg(i18n.success)
        }catch (e) {
            console.error(e);
            return this.setCode(500).setMsg(i18n.sys_err).json()
        }
    }

    @login
    @get('/api/list')
    async all() {
        try{
            await db(async conn => {
                let Menu = new Query(conn, 'sys_menu'),
                    menus = await Menu.alias('m')
                        .fields('m.*')
                        .join('sys_auth_record ar', 'ar.menu_id = m.id', 'LEFT')
                        .join('sys_user_auth ua', 'ua.auth_id = ar.auth_id', 'LEFT')
                        .where('ua.user_id', this.session.userid)
                        .order('m.sort asc')
                        .select()
                let sorted = sort2(menus)
                this.assign('menus', sorted)
            });
            return this.setCode(0).setMsg(i18n.success)
        }catch (e) {
            console.error(e)
            return this.setCode(500).setMsg(i18n.sys_err).json()
        }
    }
}
